local love = require 'love'
local fontHandler = require('assets-handler.font-handler')

local setColor = love.graphics.setColor
local drawg = love.graphics.draw
local drawRectangle = love.graphics.rectangle
local setLineWidth = love.graphics.setLineWidth
local line = love.graphics.line
local printg = love.graphics.print

local width = Width

local cards = {
    21,22,23,24,
    31,32,33,34,
    41,42,43,44,
    51,52,53,54,
    61,62,63,64,
    71,72,73,74,
    81,82,83,84,
    91,92,93,94,
    101,102,103,104,
    111,112,113,114,
    121,122,123,124,
    131,132,133,134,
    141,142,143,144
    }
local cardDict = {}
local deck = {}
local fontSize = 24

local stone = {
    image = love.graphics.newImage("assets/stone.jpg"),
    scale = 0,
}

local function convertArrayToDict(arr)
    for _, value in ipairs(arr) do
        cardDict[value] = 1 -- 1: 在牌库中；2: 不在牌库中
    end
    return cardDict
end

local function getRank(element)
    local leadingNum = math.floor(element / 10)
    local prefix = "" .. leadingNum
    if leadingNum == 11 then
        prefix = "Ⅰ"
    elseif leadingNum == 12 then
        prefix = "Ⅱ"
    elseif leadingNum == 13 then
        prefix = "Ⅲ"
    elseif leadingNum == 14 then
        prefix = "O"
    end
    return prefix
end

local function getSuit(element)
    local lastNum = element % 10
    local suffix
    if lastNum == 1 then
        suffix = '♥'
    elseif lastNum == 2 then
        suffix = '♣'
    elseif lastNum == 3 then
        suffix = '♦'
    elseif lastNum == 4 then
        suffix = '♠'
    end
    return suffix
end

local function getValue(element)
    return getRank(element) .. "  " .. getSuit(element)
end

local function init()
    cardDict = convertArrayToDict(cards)
    local widthCards = (Width - Padding) / 4
    local heightCards = (Height - Padding) / 13
    -- 创建一个 13 × 4 的二维数组，每个元素是包含4个键值对的表
    fontHandler.setFont(fontSize)
    local fontHeight = fontHandler.getFontHeight()
    for row = 1, 13 do -- Lua数组索引从1开始，因此这里是1到13
        deck[row] = {}  -- 初始化每一行的数组
        for col = 1, 4 do
            deck[row][col] = {
                deckX = Padding + (col - 1) * widthCards,
                deckY = Padding + (row - 1) * heightCards,
                width = widthCards - Padding,
                height = heightCards - Padding,
                index = (row - 1) * 4 + col,
                num = cards[(row - 1) * 4 + col],
                value = getValue(cards[(row - 1) * 4 + col]),
                valueX = Padding + (col - 1) * widthCards + (widthCards - Padding) / 2 - fontHandler.getFontWidth(getValue(cards[(row - 1) * 4 + col])) / 2,
                valueY = Padding + (row - 1) * heightCards + (heightCards - Padding) / 2 - fontHeight / 3
            }
        end
    end

    stone.scale = width / stone.image:getWidth()
end

-- 绘制最深色弃牌长方形 
local function drawRemovedRectangle(x, y, w, h)
    -- 绘制主体矩形（带颜色变化）
    setColor(0.3529, 0.4, 0.4510, 0.4) -- #5A6673(灰蓝色)
    drawRectangle("fill", x, y, w, h)

    setColor(0.2275, 0.2627, 0.3137, 0.4) -- #3A4350(深灰蓝色)
    drawRectangle("line", x, y, w, h)
end

-- 绘制叉的函数
local function drawCross(x, y, w, h)
    setColor(0.2275, 0.2627, 0.3137, 0.4) -- #3A4350(深灰蓝色)
    setLineWidth(2) -- 线条粗细

    line(x, y, x + w, y + h)
    line(x, y + h, x + w, y)
end

-- 绘制扑克牌
local function drawCards()
    setColor(1, 1, 1)
    drawg(stone.image, 0, 0, 0, stone.scale, stone.scale)

    fontHandler.setFont(fontSize)
    for row = 1, 13 do
        for col = 1, 4 do
            if cardDict[deck[row][col].num] == 1 then
                if row % 2 == 1 then
                    setColor(1, 1, 1, 0.7)
                else
                    setColor(0.9, 0.9, 0.85, 0.7) -- 米色
                end
                drawRectangle("fill", deck[row][col].deckX, deck[row][col].deckY, deck[row][col].width, deck[row][col].height)
                setColor(0.2275, 0.2627, 0.3137, 0.6) -- #3A4350(深灰蓝色)
                drawRectangle("line", deck[row][col].deckX, deck[row][col].deckY, deck[row][col].width, deck[row][col].height)

                if col % 2 == 1 then
                    setColor(1, 0, 0, 0.7)
                else
                    setColor(0, 0, 0, 0.7)
                end
                printg(deck[row][col].value, deck[row][col].valueX, deck[row][col].valueY)
            -- draw removed cards
            elseif cardDict[deck[row][col].num] ~= 1 then
                drawRemovedRectangle(deck[row][col].deckX, deck[row][col].deckY, deck[row][col].width, deck[row][col].height)
                drawCross(deck[row][col].deckX, deck[row][col].deckY, deck[row][col].width, deck[row][col].height)
            end
        end
    end
end

local function reset()
    -- 遍历并重置所有值
    for key, _ in pairs(cardDict) do
        cardDict[key] = 1
    end
end

local function getSuitChineseCharacter(element)
    local lastNum = element % 10
    local suffix
    if lastNum == 1 then
        suffix = '红心'
    elseif lastNum == 2 then
        suffix = '梅花'
    elseif lastNum == 3 then
        suffix = '方片'
    elseif lastNum == 4 then
        suffix = '黑桃'
    end
    return suffix
end

-- 发牌
local function deal(num, retained)
    math.randomseed(os.time())  -- 初始化随机种子

    -- 筛选所有值为1的键
    local cardsWithValue1 = {}
    for k, v in pairs(cardDict) do
        if v == 1 then
            table.insert(cardsWithValue1, k)
        end
    end

    -- 随机选择5个键（如果不足5个则选择全部）
    local countToChange = math.min(num, #cardsWithValue1)
    local drawnCards = {}

    -- Fisher-Yates 洗牌算法（简化版）
    for i = #cardsWithValue1, 1, -1 do
        local j = math.random(i)
        cardsWithValue1[i], cardsWithValue1[j] = cardsWithValue1[j], cardsWithValue1[i]
    end

    -- 取前countToChange个
    for i = 1, countToChange do
        drawnCards[i] = cardsWithValue1[i]
    end

    -- 添加保留牌
    if #retained > 0 then
        for _, v in ipairs(retained) do
            table.insert(drawnCards, v)
        end
    end

    -- 排序
    table.sort(drawnCards)

    -- 更新选中的键的状态为“已出”
    for _, k in ipairs(drawnCards) do
        cardDict[k] = 2
    end

    -- 输出结果
    return drawnCards
end

-- 计算卡池剩余数
local function getRemainingCardCount()
    local totalNum = 0
    for _, type in pairs(cardDict) do
        if type ==  1 then
            totalNum = totalNum + 1
        end
    end
    return totalNum
end

return{
    init = init,
    getRank = getRank,
    getSuit = getSuit,
    getSuitChineseCharacter = getSuitChineseCharacter,
    getValue = getValue,
    drawCards = drawCards,
    reset = reset,
    deal = deal,
    getRemainingCardCount = getRemainingCardCount
}